<template>
  <div id="threeContainer" style="width: 100%; height: 100%"></div>
</template>

<script>
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

export default {
  data() {
    return {
      isInitialAnimationDone: false, // 标志位
      // 其他数据属性
    };
  },
  mounted() {
    // 初始化 clock
    this.clock = new THREE.Clock();

    // 初始化 Three.js 场景
    this.initScene();
    // 加载 glTF 模型
    this.loadModel();
    // 启动动画循环
    this.animate();

    // 窗口大小变化时调整渲染器
    window.addEventListener("resize", this.onWindowResize, false);
  },
  methods: {
    // 初始化 Three.js 场景
    initScene() {
      // 创建场景
      this.scene = new THREE.Scene();
      this.scene.background = new THREE.Color(0x87cefa);

      // 创建相机
      this.camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
      );
      this.camera.position.set(0, 2, 5); //初始相机视角位置,
      // 创建渲染器
      this.renderer = new THREE.WebGLRenderer({ antialias: true });
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      this.renderer.setPixelRatio(window.devicePixelRatio); // 支持高分辨率屏幕
      document.getElementById("threeContainer").appendChild(this.renderer.domElement);

      // 添加光源
      const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
      this.scene.add(ambientLight);

      const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
      directionalLight.position.set(5, 10, 7.5);
      this.scene.add(directionalLight);

      // 添加辅助网格
      const gridHelper = new THREE.GridHelper(10, 10);
      // this.scene.add(gridHelper);

      // 初始化 OrbitControls，用于鼠标交互
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
      this.controls.enableDamping = true; // 启用阻尼效果（惯性）
      this.controls.dampingFactor = 0.25; // 阻尼系数
      this.controls.screenSpacePanning = false; // 禁止屏幕空间拖拽
      this.controls.maxPolarAngle = Math.PI / 2; // 最大俯视角度，防止翻转
      console.log(this.camera.position, "位置信息");
    },

    // 加载 glTF 模型
    loadModel() {
      const loader = new GLTFLoader();
      loader.load("/src/assets/data/gitf/gitf.gltf", (gltf) => {
        this.model = gltf.scene; // 将模型保存在 Vue 组件实例中

        this.scene.add(this.model);

        // 如果模型有动画，处理动画
        if (gltf.animations && gltf.animations.length) {
          this.mixer = new THREE.AnimationMixer(this.model);
          gltf.animations.forEach((clip) => {
            this.mixer.clipAction(clip).play();
          });
        }

        // 调整相机位置，确保模型完全显示

        // 调整模型在canvas画布中的位置，例如移动到 (0, 0, 0)
        this.model.position.set(-50, 50, 0); // 可根据需要调整坐标
        this.centerModelInView(this.model);
      });
    },
    // 调整相机位置以居中并适应模型
    centerModelInView(model) {
      const box = new THREE.Box3().setFromObject(model); // 计算模型的包围盒
      const size = box.getSize(new THREE.Vector3()); // 获取包围盒的尺寸
      const center = box.getCenter(new THREE.Vector3()); // 获取包围盒的中心

      // 设置相机位置到模型的正上方（在 y 轴上方一定高度）
      const distance = size.y * 1.5; // 设置相机离模型上方的距离，可根据模型高度调整
      // this.camera.position.set(-20, 72, 139); // 视图位置和远近

      // 相机指向模型的中心
      this.camera.lookAt(center);

      // 调整相机的近远裁剪面
      this.camera.near = size.y / 100;
      this.camera.far = size.y * 10;
      this.camera.updateProjectionMatrix();
    },
    // 动画循环
    animate() {
      requestAnimationFrame(this.animate.bind(this));

      const delta = this.clock.getDelta();
      if (this.mixer) this.mixer.update(delta);

      // 初次动画
      if (!this.isInitialAnimationDone) {
        this.camera.position.lerp(new THREE.Vector3(-20, 72, 139), 0.05); // 逐渐接近目标位置

        // 检查是否到达目标位置
        if (this.camera.position.distanceTo(new THREE.Vector3(-20, 72, 139)) < 0.1) {
          this.camera.position.set(-20, 72, 139); // 确保达到目标位置
          this.isInitialAnimationDone = true; // 标志位设置为 true
        }
      }
      // 更新 OrbitControls
      this.controls.update();
      // 输出相机位置以此来设置一个合适的视角
      // console.log(this.camera.position, '位置信息');
      this.renderer.render(this.scene, this.camera);
    },

    // 当窗口大小变化时，调整渲染器尺寸和相机
    onWindowResize() {
      this.camera.aspect = window.innerWidth / window.innerHeight;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(window.innerWidth, window.innerHeight);
    },
  },
  beforeDestroy() {
    window.removeEventListener("resize", this.onWindowResize, false);

    // 清理资源
    if (this.renderer) {
      this.renderer.dispose();
    }
    if (this.model) {
      this.scene.remove(this.model);
      this.model.traverse((object) => {
        if (object.geometry) {
          object.geometry.dispose();
        }
        if (object.material) {
          if (Array.isArray(object.material)) {
            object.material.forEach((material) => material.dispose());
          } else {
            object.material.dispose();
          }
        }
      });
    }
    if (this.mixer) {
      this.mixer.uncacheRoot(this.model);
    }
  },
};
</script>

<style scoped>
#threeContainer {
  position: absolute; /* 绝对定位，确保填充父容器 */
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: aqua;
}
</style>
